#用于哈希函数,将局面映射为一个独特的哈希值，避免重复的分析相同的棋局

import numpy as np
class ZobristHash(object):#key--可以找到棋盘状态---棋盘下的得分与策略226个，最后一个为得分
    def __init__(self,size=100000):
        self.hash_size=1<<((size-1).bit_length()-1)#哈希表大小
        self.table=np.random.randint(0,self.hash_size,size=(15,15,2)) #15*15*2每个位置为0，65536随机数
        self.values=np.random.rand(self.hash_size,226)#65536*226 0，保存key对应棋盘对应棋盘策略与得分
        self.boardcheck=np.array(np.zeros([self.hash_size,15,15,2])-1, dtype=int)#key的对应棋盘 保存棋盘状态
        self.initkey=np.random.randint(self.hash_size)#设置初始key
        print("hash size:",self.hash_size) #key的范围0-65536
    def getValue(self,boardX):
        key=self.initkey
        for ii in range(15):
            for jj in range(15):
                if(boardX[ii,jj,0]):
                    key^=self.table[ii,jj,0]
                if(boardX[ii,jj,1]):
                    key^=self.table[ii,jj,1]
        if(np.array_equal(boardX,self.boardcheck[key])):#曾经出现过该棋盘

            return key,self.values[key]#返回得分
        else:
            return key,[]
    def setValue(self,key,boardX,value):
        self.values[key]=value.copy()
        self.boardcheck[key]=boardX.copy()
